﻿#ifndef __PARSER_H_
#define __PARSER_H_
#include "ServerType.h"
#include <list>
#include <vector>
#include "Vmtype.h"
#include "log.h"
#include "Operation.h"

using namespace std;

namespace hw
{

	class Parser
	{
	public:
		Parser() = default;
		static bool next_token(const string& s, int pos, int& from, int& until) {
		    /*
		     * 在s[pos]之后（包含）查找下一个token
		     * 所谓的token是只包含字幕或者数字的连续子串
		     * [from, until)是结果，代表token的范围
		     */
            from = pos;
            while (!isalnum(s[from]) && from < (int)s.length()) {
                from ++;
            }
            if (from >= (int)s.length()) return false;
            until = from;
            while (isalnum(s[until]) && until < (int)s.length()) {
                until ++;
            }
            return true;
		}

		/*
		 * 之前的parse过不了测试，重写
		 */
		static ServerType parse_server(const std::string& s) {
		    ServerType st;
            int i = 1;
            int from = 0;
            int to = 0;
            next_token(s, i, from, to);
            st.name = s.substr(from, to-from);
            next_token(s, to, from, to);
            st.core = stoi(s.substr(from, to-from));
            next_token(s, to, from, to);
            st.memory = stoi(s.substr(from, to-from));
            next_token(s, to, from, to);
            st.hardware_price = stoi(s.substr(from, to-from));
            next_token(s, to, from, to);
            st.daily_cost = stoi(s.substr(from, to-from));
            return st;
		}

		static Vmtype parse_vm(const std::string& s) {
            Vmtype vmtype;
            int from = 1;
            int to = 2;
            next_token(s, from, from, to);
            vmtype.name = s.substr(from, to-from);
            next_token(s, to, from, to);
            vmtype.core = stoi(s.substr(from, to-from));
            next_token(s, to, from, to);
            vmtype.memory = stoi(s.substr(from, to-from));
            next_token(s, to, from, to);
            vmtype.is_double = (s[from] == '1');
            return vmtype;
		}

		static Operation parse_operation(const std::string& s) {
            Operation op;
            int from = 1;
            int to = 2;
            next_token(s, from, from, to);
            op.mode = (s[from] == 'a' ? Op::ADD : Op::DEL);
            if (op.mode == Op::ADD) {
                next_token(s, to, from, to);
                op.vm_type_id = s.substr(from, to-from);
                next_token(s, to, from, to);
                op.vmid = s.substr(from, to-from);
            } else {
                next_token(s, to, from, to);
                op.vmid = s.substr(from, to-from);
            }
            return op;
		}

		static vector<int> parse_ints(const std::string& s, char delim) {
            int start = 0;
            vector<int> res;
            while (start < s.length()) {
                if (s[start] == delim) {
                    start++; continue;
                }

                int end = start+1;
                while (end < s.length() && s[end] != delim) end++;
                res.push_back(stoi(s.substr(start, end-start)));
                start = end+1;
            }
            return res;
		}
	};
};	   // namespace hw
#endif // !__PARSER__